const StockModel = require("../../model/stockmodel");
const StockRequest = require("../../request/stock");
const LineModel = require("../../model/linemodel");
const LineIterModel = require("../../model/lineitermodel")
const {
	StockEnum,
	CodeEnum
} = require("../../enum");
const {
	isString,
	isArray,
	now,
	getLastDayInMonth,
	getDayInWeek
} = require("../../utils")
module.exports = class StockLogic {
	static async getSymbolList() {
		const stock = new StockModel();
		// return await stock.getSymbolList();
	}
	// 更新 day week month
	static async updateLineWithStock(symbol = "", lineType = "") {
		try {
			const line = new LineModel();
			const lineItem = new LineIterModel();
			const lastDates = await line.getLastDate(symbol);
			const curDate = now("YYYY-MM-DD");
			let lastDate = lastDates[lineType];
			// 当前时间等于最想更新时间跳过
			if (lastDate == curDate) {
				return 0;
			}
			const {
				data: {
					data: {
						[symbol]: lineList = {}
					} = {}
				} = {}
			} = await StockRequest.getLineForStock({
				symbol,
				cycle: 640,
				type: lineType,
				start: lastDate
			}) || {};

			const avildLineList = lineList[`qfq${lineType}`] || lineList[lineType];
			const preList = [];
			if (avildLineList) {
				for (let avildLineIter of avildLineList) {
					const itemInstance = lineItem.getNeatInstance();
					itemInstance.current_date = avildLineIter[0]; //当前日期
					itemInstance.opening_price = avildLineIter[1]; //开盘价
					itemInstance.closing_price = avildLineIter[2]; //收盘价
					itemInstance.ceiling_price = avildLineIter[3]; //最高价
					itemInstance.floor_price = avildLineIter[4]; //最低价
					itemInstance.turnover = avildLineIter[5]; //成交量
					itemInstance.turnover_rate = avildLineIter[7]; //换手率
					itemInstance.transaction_volume = avildLineIter[8]; //成交额
					preList.push(itemInstance);
				}
			}

			const filterList = preList.filter(fi => {
				return fi.current_date > lastDate
			});
			let updateStatus = 0;
			if (filterList && filterList.length) {
				updateStatus = await line.pushLineData(symbol, lineType, filterList, curDate);
			}
			return updateStatus;
		} catch (e) {
			return CodeEnum.EXCEPTION
		}

	}
	// 插入 
	static async insertLineForStock(symbol = "") {
		try {
			const line = new LineModel();
			const lineItem = new LineIterModel();
			const lineInstance = await line.getNeatInstance();
			const curDate = now("YYYY-MM-DD");
			lineInstance.symbol = symbol;
			lineInstance.create_date = curDate;
			lineInstance.lastupdate_date = curDate;
			for (let lineType of ["day", "week", "month"]) {
				const {
					data: {
						data: {
							[symbol]: lineList = {}
						} = {}
					} = {}
				} = await StockRequest.getLineForStock({
					symbol,
					cycle: 640,
					type: lineType,
				}) || {};

				const avildLineList = lineList[`qfq${lineType}`] || lineList[lineType];
				const preList = [];
				if (avildLineList) {
					for (let avildLineIter of avildLineList) {
						const itemInstance = lineItem.getNeatInstance();
						itemInstance.current_date = avildLineIter[0]; //当前日期
						itemInstance.opening_price = avildLineIter[1]; //开盘价
						itemInstance.closing_price = avildLineIter[2]; //收盘价
						itemInstance.ceiling_price = avildLineIter[3]; //最高价
						itemInstance.floor_price = avildLineIter[4]; //最低价
						itemInstance.turnover = avildLineIter[5]; //成交量
						itemInstance.turnover_rate = avildLineIter[7]; //换手率
						itemInstance.transaction_volume = avildLineIter[8]; //成交额
						preList.push(itemInstance);
					}
				}
				lineInstance[lineType] = preList;
			}
			const insertedRes = await line.insert(lineInstance);
			console.log("inserted", symbol, insertedRes);
			return insertedRes
		} catch (e) {
			return CodeEnum.EXCEPTION
		}
	}

	static async refreshBatchOfLinesForStock(lineType, symbolList = []) {
		console.log("更新数据 start ");
		// 遍历集合 
		const stock = new StockModel();
		const line = new LineModel();
		const pageSize = 10;
		const excePromises = [];
		const preSymbols = [];
		symbolList = await line.getSymbolList();
		const lg = symbolList.length;
		for (let i = 0; i < lg; i++) {
			const symbol = symbolList[i];
			const index = i + 1;
			const remainder = index % pageSize;
			excePromises.push(this.updateLineToDayWithStock(symbol, lineType));
			preSymbols.push(symbol);
			if ([0, lg].includes(remainder)) {
				const resList = await Promise.all(excePromises);
				excePromises.length = 0;
				preSymbols.length = 0;
				console.log(lg, index, resList);

			}

		}
		return CodeEnum.SUCCESS
		console.log("更新数据 end ");
	}
	// 批量新增股票基本信息
	static async refreshBatchOFBasesForStock() {
		const stock = new StockModel();
		// 获取symbol数组集合
		// 初识化 getSymbolList(true)
		const symbolList = await stock.getSymbolList();
		if (!symbolList) {
			return CodeEnum.ERROR_STOCK_SYMBOLS
		}
		const nodes = [
			StockEnum.TYPE_CODE_SH_A,
			StockEnum.TYPE_CODE_SH_B,
			StockEnum.TYPE_CODE_SZ_A,
			StockEnum.TYPE_CODE_SZ_B
		];
		const pageSize = 50;
		for (let node of nodes) {
			const {
				data: total
			} = await StockRequest.getTotalByNodeForStock(node) || {};
			let totalInt = Number.parseInt(total);
			const count = Math.ceil(totalInt / pageSize);
			let promises = [];
			for (let i = 1; i <= count; i++) {
				const {
					data
				} = await StockRequest.getBaseInfoForStock({
					page: i,
					num: pageSize,
					node
				}) || {};
				if (isArray(data) && data.length) {
					// 更新 >>> start <<<
					for (let mi of data) {
						const preModel = stock.getNeatInstance();
						preModel.symbol = mi.symbol; // 股票标识
						preModel.code = mi.code; // 编码
						preModel.name = mi.name; // 名称
						// --
						preModel.trade = mi.trade; // 实时交易价
						preModel.price_change = mi.pricechange; // 涨跌额
						preModel.change_percent = mi.changepercent; // 涨跌幅
						preModel.buy = mi.buy; // 买入价
						preModel.sell = mi.sell; // 卖出价
						preModel.float_yclose = mi.settlement; // 昨日收盘价
						preModel.open = mi.open; // 开盘价
						preModel.high = mi.high; // 最高价
						preModel.low = mi.low; // 最低价
						preModel.volume = mi.volume; // 成交量(手)
						preModel.amount = mi.amount; // 成交额(元)
						preModel.tick_time = mi.ticktime; // 数据实时获取时间
						preModel.pe = mi.per; // 市盈率
						preModel.pb = mi.pb; // 市净率
						preModel.market_capitalization = mi.mktcap; // 市值(元)
						preModel.turnover_rate = mi.turnoverratio; // 换手率
						// --
						preModel.stock_type_code = node; //股票类型代号
						preModel.stock_type_name = StockEnum.map(node); //股票类型名称
						preModel.exchange_code = node.startsWith("sh") ? StockEnum.EXCHANGE_CODE_SH :
							StockEnum
							.EXCHANGE_CODE_SZ; //交易所代号
						preModel.exchange_name = node.startsWith("sh") ? StockEnum.EXCHANGE_NAME_SH :
							StockEnum
							.EXCHANGE_NAME_SZ; //交易所名称
						preModel.create_date = now("YYYY-MM-DD"); // 创建时间
						preModel.lastupdate_date = now("YYYY-MM-DD"); // 最后更新时间
						const symbol = mi.symbol;
						if (symbolList.includes(symbol)) {
							delete preModel.symbol
							delete preModel.code
							delete preModel.stock_type_code
							delete preModel.stock_type_name
							delete preModel.exchange_code
							delete preModel.exchange_name
							delete preModel.create_date
							// 更新
							promises.push(stock.updateBaseBySymbol(symbol, preModel));
						} else {
							// 新增 stock 
							const inserted = await stock.insert(preModel);
							// 新增 line
							await this.insertLineForStock(symbol);
							console.log("insert -->", symbol, "-->", inserted);
						}
					}
				}
				// 执行
				const exeAllRes = await Promise.all(promises);
				promises.length = 0;
				console.log(i * pageSize, exeAllRes);
			}


		}

	}


}
